#include "../include/rkmedia.h"
#include <cstdint>
#include <stdio.h>
#include <string.h>

int VI_init(VI_CHN_ATTR_S* vi0_chn_attr, RK_S32 CamId)
{
    /*------------VI0模块初始化-------------*/
    vi0_chn_attr->pcVideoNode = pDeviceName; // Video节点
    vi0_chn_attr->u32BufCnt = 3; // VI模块捕获视频缓冲区个数
    vi0_chn_attr->u32Width = video_width; // video宽度
    vi0_chn_attr->u32Height = video_height; // video高度
    vi0_chn_attr->enPixFmt = IMAGE_TYPE_NV12; // video图像像素格式
    vi0_chn_attr->enBufType = VI_CHN_BUF_TYPE_DMA; // VI 捕获视频缓冲区类型，视频流的类型
    vi0_chn_attr->enWorkMode = VI_WORK_MODE_NORMAL; // VI工作模式
    //设置VI模块属性
    int ret = RK_MPI_VI_SetChnAttr(CamId, 0, vi0_chn_attr);
    if(ret != 0)
    {
        printf("RK_MPI_VI0_SetChnAttr failed!\n");
        return -1;
    }
    //使能VI模块
    ret = RK_MPI_VI_EnableChn(CamId, 0);
    if(ret != 0)
    {
        printf("RK_MPI_VI0_EnableChn failed!\n");
        return -1;
    }

    return 0;
}

int VENC_init(VENC_CHN_ATTR_S* venc_chn_attr)
{
    /*------------VENC模块初始化-------------*/
    memset(venc_chn_attr, 0, sizeof(*venc_chn_attr)); // 清空VENC通道属性结构体变量venc_chn_attr
    venc_chn_attr->stVencAttr.enType = RK_CODEC_TYPE_H264; // 指定编码协议类型为H.264
    venc_chn_attr->stRcAttr.enRcMode = VENC_RC_MODE_H264CBR; // 码率控制模式选择CBR
    venc_chn_attr->stRcAttr.stH264Cbr.u32Gop = 10; // I帧间隔
    venc_chn_attr->stRcAttr.stH264Cbr.u32BitRate = venc_width * venc_height; // 平均比特率，取值范围：[2000, 98000000]bps
    // 编码的帧率 =目标帧率分子 / 目标帧率分母 输入码流的帧率 =数据源帧率分子 / 数据源帧率分母
    venc_chn_attr->stRcAttr.stH264Cbr.fr32DstFrameRateDen = 1; // 目标帧率分母
    venc_chn_attr->stRcAttr.stH264Cbr.fr32DstFrameRateNum = 30; // 目标帧率分子
    venc_chn_attr->stRcAttr.stH264Cbr.u32SrcFrameRateDen = 1; // 数据源帧率分母
    venc_chn_attr->stRcAttr.stH264Cbr.u32SrcFrameRateNum = 30; // 数据源帧率分子

    venc_chn_attr->stVencAttr.imageType = IMAGE_TYPE_RGB888; // 输入图像格式类型
    venc_chn_attr->stVencAttr.u32PicWidth = venc_width; // 编码图像宽度，以像素为单位
    venc_chn_attr->stVencAttr.u32PicHeight = venc_height; // 编码图像高度，以像素为单位
    venc_chn_attr->stVencAttr.u32VirWidth = venc_width; // stride宽度，通常设置等于图像的宽
    venc_chn_attr->stVencAttr.u32VirHeight = venc_height; // stride高度，通常设置等于图像的高
    venc_chn_attr->stVencAttr.u32Profile = 77; // 压缩的档次为Main profile 77 为main profile
    int ret = RK_MPI_VENC_CreateChn(0, venc_chn_attr); // 创建编码通道（采用通道0）
    if(ret != 0)
    {
        printf("RK_MPI_VENC_CreateChn failed!\n");
        return -1;
    }

    return 0;
}

int init_rga(RGA_ATTR_S* stRgaAttr)
{
    /*------------rga初始化-------------*/
    memset(stRgaAttr, 0, sizeof(*stRgaAttr));
    stRgaAttr->bEnBufPool = RK_TRUE;
    stRgaAttr->u16BufPoolCnt = 3;
    stRgaAttr->u16Rotaion = 0;
    stRgaAttr->stImgIn.u32X = 0;                        //裁剪原始区域的起始位置
    stRgaAttr->stImgIn.u32Y = 0;
    stRgaAttr->stImgIn.imgType = IMAGE_TYPE_NV12;
    stRgaAttr->stImgIn.u32Width = video_width;                
    stRgaAttr->stImgIn.u32Height = video_height;
    stRgaAttr->stImgIn.u32HorStride = video_width;            
    stRgaAttr->stImgIn.u32VirStride = video_height;
    stRgaAttr->stImgOut.u32X = 0;
    stRgaAttr->stImgOut.u32Y = 0;
    stRgaAttr->stImgOut.imgType = IMAGE_TYPE_BGR888;
    stRgaAttr->stImgOut.u32Width = video_width;                
    stRgaAttr->stImgOut.u32Height = video_height;
    stRgaAttr->stImgOut.u32HorStride = video_width;
    stRgaAttr->stImgOut.u32VirStride = video_height;
    int ret = RK_MPI_RGA_CreateChn(0, stRgaAttr);
    if (ret) {
        printf("Create rga[0] falied! ret=%d\n", ret);
        return -1;
    }

    memset(stRgaAttr, 0, sizeof(*stRgaAttr));
    stRgaAttr->bEnBufPool = RK_TRUE;
    stRgaAttr->u16BufPoolCnt = 1;
    stRgaAttr->u16Rotaion = 0;
    stRgaAttr->stImgIn.u32X = 0;                        //裁剪原始区域的起始位置
    stRgaAttr->stImgIn.u32Y = 0;
    stRgaAttr->stImgIn.imgType = IMAGE_TYPE_BGR888;
    stRgaAttr->stImgIn.u32Width = video_width;                
    stRgaAttr->stImgIn.u32Height = video_height;
    stRgaAttr->stImgIn.u32HorStride = video_width;            
    stRgaAttr->stImgIn.u32VirStride = video_height;
    stRgaAttr->stImgOut.u32X = 0;
    stRgaAttr->stImgOut.u32Y = 0;
    stRgaAttr->stImgOut.imgType = IMAGE_TYPE_BGR888;
    stRgaAttr->stImgOut.u32Width = 640;                
    stRgaAttr->stImgOut.u32Height = 640;
    stRgaAttr->stImgOut.u32HorStride = 640;
    stRgaAttr->stImgOut.u32VirStride = 640;
    ret = RK_MPI_RGA_CreateChn(1, stRgaAttr);
    if (ret) {
        printf("Create rga[1] falied! ret=%d\n", ret);
        return -1;
    }

    return 0;
}

int VI_RGA_Bind(MPP_CHN_S* stSrcChn, MPP_CHN_S* stDestChn, RK_S32 chnid)
{
    // 通道绑定
    stSrcChn->enModId = RK_ID_VI; // 模块号
    stSrcChn->s32DevId = 0; // 设备号
    stSrcChn->s32ChnId = chnid; // 通道号
    stDestChn->enModId = RK_ID_RGA;
    stDestChn->s32DevId = 0;
    stDestChn->s32ChnId = chnid;
    int ret = RK_MPI_SYS_Bind(stSrcChn, stDestChn); // 将数据源和数据接收者进行绑定
    return ret;
}